package de.adorsys.beanstest.plugin.facet; import java.io.FileNotFoundException; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.enterprise.inject.Alternative; import javax.enterprise.inject.Produces; import javax.enterprise.inject.Stereotype; import org.jboss.forge.parser.JavaParser; import org.jboss.forge.parser.java.JavaAnnotation; import org.jboss.forge.parser.java.JavaClass; import org.jboss.forge.parser.java.Method; import org.jboss.forge.project.dependencies.Dependency; import org.jboss.forge.project.dependencies.DependencyBuilder; import org.jboss.forge.project.facets.BaseFacet; import org.jboss.forge.project.facets.DependencyFacet; import org.jboss.forge.project.facets.JavaSourceFacet; import org.jboss.forge.resources.java.JavaResource; import org.jboss.forge.shell.ShellMessages; import org.jboss.forge.shell.plugins.Alias; import org.jboss.forge.shell.plugins.PipeOut; import org.jboss.forge.shell.plugins.RequiresFacet; import org.jboss.shrinkwrap.descriptor.api.spec.cdi.beans.BeansDescriptor; import de.adorsys.beanstest.plugin.BeanstestConfiguration; @Alias("beanstest.MockitoFacet") @RequiresFacet({ DependencyFacet.class, JavaSourceFacet.class, CDITestFacet.class }) public class MockitoFacet extends BaseFacet { public static final Dependency MOCKITO = DependencyBuilder.create("org.mockito:mockito-all:1.9.5:test"); public static final String ALTERNATIVE_STEREOTYPE_NAME = "BeanstestAlternative"; @Override public boolean install() { // add mockito dependency DependencyFacet dependencyFacet = project.getFacet(DependencyFacet.class); dependencyFacet.addDirectDependency(MOCKITO); // create AlternativesProducer JavaClass alternativesProducer = JavaParser.parse(JavaClass.class, getClass().getResourceAsStream("/de/adorsys/beanstest/AlternativesProducer.jv")); try { JavaResource altResource = getAlternativesProducer(); altResource.setContents(alternativesProducer); } catch (FileNotFoundException e) { throw new RuntimeException("AlternativesProducer could not be created", e); } return true; } @Override public boolean isInstalled() { DependencyFacet dependencyFacet = getProject().getFacet(DependencyFacet.class); boolean mockitoDep = dependencyFacet.hasEffectiveDependency(DependencyBuilder.create(MOCKITO)); boolean alternativesProducer = false; try { alternativesProducer = getAlternativesProducer().exists(); } catch (Exception e) {} return mockitoDep && alternativesProducer; } public void createMockProducer(JavaResource type, String stereotype, PipeOut out) throws FileNotFoundException { final JavaSourceFacet java = project.getFacet(JavaSourceFacet.class); final String beanstestPackage = java.getBasePackage() + BeanstestConfiguration.PACKAGESUFFIX; JavaResource alternativesResource = getAlternativesProducer(); try { type.exists(); } catch (Exception e) { ShellMessages.warn(out, "Type does not exist in source folder (compile error might occur): " + type); } JavaClass alternativesClass = JavaParser.parse(JavaClass.class, alternativesResource.getResourceInputStream()); alternativesClass.setPackage(beanstestPackage); String className = java.calculateName(type); String packageName = java.calculatePackage(type); //add import alternativesClass.addImport(packageName + "." + className); //add producer method Method<JavaClass> producerMethod = alternativesClass.addMethod("public " + className + " produce" + className + "()"); //:( producerMethod.addAnnotation(Produces.class); producerMethod.setBody("return mock(" + className + ".class);"); //handle alternative annotation and beans.xml entry if (stereotype == null) { stereotype = ALTERNATIVE_STEREOTYPE_NAME; } //handle stereotype createStereotype(beanstestPackage, stereotype); producerMethod.addAnnotation(stereotype); alternativesResource.setContents(alternativesClass); } private void createStereotype(String beanstestPackage, String stereotype) throws FileNotFoundException { // @Stereotype // @Alternative // @Target(ElementType.METHOD) // @Retention(RetentionPolicy.RUNTIME) // public @interface BeanstestAlternative { // } //TODO how do i create a nested annotation with Forge ? JavaResource stereotypeResource = getStereotype(stereotype); if (!stereotypeResource.exists()) { JavaAnnotation javaAnnotation = JavaParser.create(JavaAnnotation.class); javaAnnotation.setName(stereotype); javaAnnotation.setPackage(beanstestPackage); javaAnnotation.addAnnotation(Stereotype.class); javaAnnotation.addAnnotation(Alternative.class); javaAnnotation.addAnnotation(Target.class).setEnumValue(ElementType.METHOD); javaAnnotation.addAnnotation(Retention.class).setEnumValue(RetentionPolicy.RUNTIME); stereotypeResource.setContents(javaAnnotation); BeansDescriptor beansDescriptor = project.getFacet(CDITestFacet.class).getConfig(); if (!beansDescriptor.getAlternativeStereotypes().contains(javaAnnotation.getCanonicalName())) { beansDescriptor.alternativeStereotype(javaAnnotation.getCanonicalName()); project.getFacet(CDITestFacet.class).saveConfig(beansDescriptor); } } } private JavaResource getAlternativesProducer() throws FileNotFoundException { final JavaSourceFacet java = project.getFacet(JavaSourceFacet.class); return java.getTestJavaResource((java.getBasePackage() + BeanstestConfiguration.PACKAGESUFFIX).replaceAll("\\.", "/")+ "/AlternativesProducer.java"); } private JavaResource getStereotype(String stereotype) throws FileNotFoundException { final JavaSourceFacet java = project.getFacet(JavaSourceFacet.class); return java.getTestJavaResource((java.getBasePackage() + BeanstestConfiguration.PACKAGESUFFIX).replaceAll("\\.", "/")+ "/"+ stereotype + ".java"); } }